﻿using System;
using System.IO;
using System.Collections.Generic;
using System.Text;
using System.Reflection;

using Mighty.Lib.SensedTypes;

namespace Mighty.Lib
{
    class ParsedTypesTree
    {


        private Dictionary<string, IClass> _loadedClasses = null;
        private Dictionary<string, ISensedType> _loadedInterfaces = null;
        private Dictionary<string, ISensedType> _loadedMembers = null;
        private Dictionary<string, ISensedType> _loadedMethods = null;
        private Dictionary<string, INamespace> _loadedNamespaces = null;
        private Dictionary<string, ISensedType> _loadedProperties = null;
        private Dictionary<string, ISensedType> _loadedValueTypes = null;
        private List<ISensedType> _tree = null;


        public ParsedTypesTree()
        {
            
            _loadedClasses = new Dictionary<string, IClass>();
            _loadedInterfaces = new Dictionary<string, ISensedType>();
            _loadedNamespaces = new Dictionary<string, INamespace>();
            _loadedMembers = new Dictionary<string, ISensedType>();
            _loadedMethods = new Dictionary<string, ISensedType>();
            _loadedProperties = new Dictionary<string, ISensedType>();
            _loadedMethods = new Dictionary<string, ISensedType>();
        }

        public void LoadAssemblyIntoTree(string assemblyName)
        {
            // first try to load from file
            Assembly asm = null;
            try
            {
                asm = Assembly.LoadFile(assemblyName);
            }
            catch (FileNotFoundException e)
            {
                // the provided path isn't a file, so let's
                // try and load it from the cache
                try
                {
                    asm = Assembly.Load(assemblyName);
                }
                catch (Exception ex)
                {
                    
                    throw new Exception("Attempt to load assembly from file and from GAC failed or file "+e.FileName+" cannot be found. We suck: " + ex.ToString());
                }

            }

            // so anywho we make it here which means it's now time to parse the assembly
            Type[] types = asm.GetExportedTypes();
            foreach (Type type in types)
            {
                if (!_loadedNamespaces.ContainsKey(type.Namespace))
                {
                    // need to add this namespace
                    // FIXME: turn this into fetching from a provider...?
                    Namespace ns = new Namespace(type.Namespace);
                    _loadedNamespaces.Add(ns.Name, ns);
                }
                
                // now we get to pigeon-hole the object
                if (type.IsClass)
                {
                    Class cls = new Class(type, _loadedNamespaces[type.Namespace]);

                    // now let's parse this sucker and build it up with child objects
 


                    // then add it as a child under it's parent namespace
                    _loadedNamespaces[type.Namespace].Children.Add(cls);
                    // and add it to the list o classes
                    _loadedClasses.Add(cls.Name, cls);
                    // and of course add it to the tree
                    _tree.Add(cls);
                }


            }

            
        }

    }
}
